package gee

import (
	"net/http"
	"strings"
)

type router struct {
	handlers map[string]HandlerFunc
	// roots为动态路由构建trie准备的，纯静态路由用不到构建trie，直接全部写入handlers的key即可
	roots map[string]*node //分为GET、POST等多个root
}

func newRouter() *router {
	return &router{
		make(map[string]HandlerFunc),
		make(map[string]*node),
	}
}

func parsePattern(pattern string) []string {
	parts := strings.Split(pattern, "/")
	res := make([]string, 0)
	for _, part := range parts {
		if part != "" {
			res = append(res, part)
			if part[0] == '*' {
				break
			}
		}
	}
	return res
}

func (r *router) addRoute(method string, pattern string, handler HandlerFunc) {
	parts := parsePattern(pattern)
	key := method + "-" + pattern

	// 如果没有根节点则创建一个根节点，根节点就是GET、POST等
	if n := r.roots[method]; n == nil {
		r.roots[method] = &node{}
	}

	// 将路由插入到树中，使用GET、POST的等不同的方法建立多个树
	r.roots[method].insert(pattern, parts, 0)

	r.handlers[key] = handler
}

func (r *router) getRoute(method string, pattern string) (*node, map[string]string) {
	// 解析请求中的具体path
	searchParts := parsePattern(pattern)
	params := make(map[string]string)
	// 先找到所在树
	root := r.roots[method]
	if root == nil {
		return nil, nil
	}

	n := r.roots[method].search(searchParts, 0)
	if n != nil {
		// 这是建树的时候的那个路径，包含/*和/:id这些内容
		parts := parsePattern(n.pattern)
		for i, part := range parts {
			if part[0] == ':' {
				params[part[1:]] = searchParts[i]
			}
			// 只有*没有后续就没法写出映射
			if part[0] == '*' && len(part) > 1 {
				params[part[1:]] = strings.Join(searchParts[i:], "/")
				break
			}
		}
		return n, params
	}
	return nil, nil
}

func (r *router) handle(c *Context) {
	// 获取前缀树中的pattern，为了给handler中取出路由处理函数用，因为真实路径是动态路径，路由处理函数对应的key是前缀树中的模板路由
	n, params := r.getRoute(c.Method, c.Path)
	if n != nil {
		c.Params = params
		key := c.Method + "-" + n.pattern
		r.handlers[key](c)
	} else {
		c.String(http.StatusNotFound, "404 NOT FOUND: %s\n", c.Path)
	}
}
